from gaev.actions import TemplateAction
from gaev.actions import get_actions_details
from gaev.actions.url import get_action_url 
from gaev import utils
from gaev import HumanizeContext
from gaev import exceptions


class Action(TemplateAction):
	image_url='/static/images/icon_details.gif'
	template='base_details.html'
	
	def get_name(self):
		return 'details'
	
	def perform_template(self):
		entity=self.object
		sections=entity.get_details_sections()
		sections_params=[]
		for section in sections:
			section.assign_action(self)
			params=section.get_params()
			if 'template' in params:
				raise exceptions.TemplateNameError('Cannot use "template" parameter in details section.')
			params['template']=section.template
			sections_params.append(params)
		params['sections']=sections_params
		return params


class Section(object):
	template = None
	def assign_action(self, action):
		self.action=action
		
	def get_entity(self):
		return self.action.object
	entity=property(get_entity)
	def get_request(self):
		return self.action.request
	request=property(get_request)
	
	
	def get_params(self):
		pass
	
class PropertyListSection(Section):
	template='details/property_list.html'
	humanize_context=HumanizeContext(use_html=True)
	
	def get_params(self):
		entity=self.entity
		model=entity.__class__
		cols=model.get_columns()
		captions=model.get_column_captions(cols)
		details=entity.get_humanized_properties(self.humanize_context)
		params={'details': details, 'cols': cols, 'captions': captions}
		return params

class ActionsSection(Section):
	template='details/actions.html'
	
	def get_params(self):
		entity=self.entity
		actions=get_actions_details(entity)
		actions=utils.filter(lambda x:x['name']!='details', actions)
		
		params={'actions': actions}
		return params

class ReferringEntitiesSection(Section):
	template='details/referring_entities.html'
	humanize_context=HumanizeContext(use_html=True)
	max_object_count=10
	def __init__(self, referring_property):
		self.referring_property=referring_property
	
	def get_referring_entities_query(self):
		model=self.referring_property.model_class
		prop_name=self.referring_property.name
		filter_string='%s = ' % prop_name
		query=model.entities().all().filter(filter_string, self.entity)
		if model.get_default_ordering():
			query.order(model.get_default_ordering())
		return query
		
	def get_params(self):
		prop=self.referring_property
		model=prop.model_class

		entities_query=self.get_referring_entities_query()
		entities=entities_query.fetch(self.max_object_count)
		if len(entities)==self.max_object_count:
			entities_count=entities_query.count()
		else:
			entities_count=len(entities)
		
		refmodel_caption=model.get_model_caption()
		if utils.camelcase_to_underscore(model.__name__)==prop.name:
			prop_caption=None
		else:
			prop_caption=prop.get_caption()
		prop_caption=prop.get_caption()

		descriptions=[]
		for entity in entities:
			desc=utils.humanize_reference(entity, self.humanize_context)
			descriptions.append(desc)
		
		from gaev.model.restrictor import ReferenceRestrictor
		from gaev import actions
		restrictor=ReferenceRestrictor(prop.model_class.entities(), prop, self.entity)
		all_url=get_action_url('index', restrictor.get_restricted_entity_set())

		params={
			'referer': refmodel_caption,
			'referring_property': prop_caption,
			'all_url': all_url,
			'entities_but_last': descriptions[:-1],
			}
		if len(entities)>0:
			params['last_entity']=descriptions[-1]

		if entities_count>len(entities):
			params['remaining']=entities_count-len(entities)
		return params
		
		
